package cn.charlotte.pit.commands.player;


import cn.charlotte.pit.ThePit;
import cn.charlotte.pit.commands.PitCommands;
import cn.charlotte.pit.data.PlayerProfile;
import cn.charlotte.pit.manager.ResourceManager;
import cn.charlotte.pit.perk.AbstractPerk;
import cn.charlotte.pit.perk.TypedPerk;
import cn.charlotte.pit.util.chat.CC;
import cn.charlotte.pit.util.rank.RankUtil;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.Default;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.event.HoverEvent;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.BookMeta;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@CommandAlias("killRecap|killrecap|recap")
public class KillRecap extends BaseCommand {
    private final PitCommands pitCommands;
    private final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");

    public KillRecap(PitCommands pitCommands) {
        this.pitCommands = pitCommands;
    }

    @Default
    public void onCheckKillRecap(Player player) {

        try {
            cn.charlotte.pit.data.sub.KillRecap killRecap = cn.charlotte.pit.data.sub.KillRecap.recapMap.get(player.getUniqueId());
            if (killRecap == null || killRecap.getKiller() == null || killRecap.getAssistData() == null) {
                player.sendMessage(CC.translate("&c&l错误! &7未找到有效的近期死亡回放数据,抱歉!"));
                return;
            }

            ItemStack recapBook = new ItemStack(Material.WRITTEN_BOOK);
            BookMeta bookMeta = (BookMeta) recapBook.getItemMeta();

            bookMeta.setTitle(player.getName());
            bookMeta.setAuthor("ThePit");

            Component newLine = Component.text("\n");
            Component splitLine = Component.text("\n\n");
            PlayerProfile playerProfile = PlayerProfile.getPlayerProfileByUuid(player.getUniqueId());
            PlayerProfile killerProfile = PlayerProfile.getPlayerProfileByUuid(killRecap.getKiller());

            List<Component> texts = new ArrayList<>();
            texts.add(Component.text("§c§l战斗日志"));
            texts.add(newLine);
            texts.add(Component.text("§8" + dateTimeFormatter.format(LocalDateTime.now())));
            texts.add(newLine);
            texts.add(Component.text(RankUtil.getPlayerColoredName(player.getUniqueId())));
            texts.add(newLine);
            texts.add(Component.text("击杀者: "));
            texts.add(newLine);
            Component killerName = LegacyComponentSerializer.legacyAmpersand().deserialize(RankUtil.getPlayerColoredName(killRecap.getKiller()));


            List<TypedPerk<?>> collect = ThePit.getInstance()
                    .getPerkFactory()
                    .getPerks()
                    .stream()
                    .filter(abstractPerk -> killRecap.getPerk().contains(abstractPerk.getInternalPerkName()))
                    .toList();
            StringBuilder killerHover = new StringBuilder();
            killerHover.append(killerProfile.getFormattedName())
                    .append("\n");
            for (TypedPerk<?> perk : collect) {
                killerHover.append(CC.translate("&e"))
                        .append(perk.getDisplayName())
                        .append("\n");
            }


            texts.add(killerName.hoverEvent(HoverEvent.showText(Component.text(CC.translate(killerHover.toString())))));


//            StringBuilder killerCoin = new StringBuilder();
//            killerCoin.append(CC.translate("&f基础奖励: &6+" + this.pitCommands.numFormat.format(killRecap.getBaseCoin())))
//                    .append("\n");
            String goldBreakdown = getGoldBreakdown(killRecap.getResourceManager());
            String expBreakdown = getExpBreakdown(killRecap.getResourceManager());

//            StringBuilder killerExp = new StringBuilder();
//            killerExp.append(CC.translate("&f基础奖励: &b+" + this.pitCommands.numFormat.format(killRecap.getBaseExp())))
//                    .append("\n");
//            if (killRecap.getNotStreakExp() > 0) {
//                killerExp.append(CC.translate("&f首杀奖励: &b+" + this.pitCommands.numFormat.format(killRecap.getNotStreakExp())))
//                        .append("\n");
//            }
//            if (killRecap.getLevelDisparityExp() > 0) {
//                killerExp.append(CC.translate("&f等级/装备差距: &b+" + this.pitCommands.numFormat.format(killRecap.getLevelDisparityExp())))
//                        .append("\n");
//            }
//            if (killRecap.getOtherExp() > 0) {
//                killerExp.append(CC.translate("&f其他奖励: &b+" + this.pitCommands.numFormat.format(killRecap.getOtherExp())))
//                        .append("\n");
//            }
            TextComponent coinsInfo = Component.text(CC.translate("&6+" + this.pitCommands.numFormat.format(killRecap.getResourceManager().calculateGold()) + "硬币"))
                    .hoverEvent(HoverEvent.showText(Component.text(goldBreakdown)));
            TextComponent xpInfo = Component.text(CC.translate(" &b+" + this.pitCommands.numFormat.format(killRecap.getResourceManager().calculateEXP()) + "经验值"))
                    .hoverEvent(HoverEvent.showText(Component.text(expBreakdown)));
            texts.add(coinsInfo);
            texts.add(xpInfo);
            texts.add(newLine);

            int i = 1;
            texts.add(Component.text(CC.translate("&0助攻 (" + killRecap.getAssistData().size() + "):")));
            texts.add(newLine);

            for (cn.charlotte.pit.data.sub.KillRecap.AssistData assistData : killRecap.getAssistData()) {
                StringBuilder assistCoin = new StringBuilder();
                assistCoin.append(CC.translate("&f基础奖励: &6+" + this.pitCommands.numFormat.format(killRecap.getBaseCoin() * assistData.getPercentage())))
                        .append("\n");
                if (assistData.getStreakCoin() > 0) {
                    assistCoin.append(CC.translate("&f连杀奖励: &6+" + this.pitCommands.numFormat.format(assistData.getStreakCoin())))
                            .append("\n");
                }
                if (assistData.getLevelDisparityCoin() > 0) {
                    assistCoin.append(CC.translate("&f等级/装备差距: &6+" + this.pitCommands.numFormat.format(assistData.getLevelDisparityCoin())))
                            .append("\n");
                }
                StringBuilder assistExp = new StringBuilder();
                assistExp.append(CC.translate("&f基础奖励: &b+" + this.pitCommands.numFormat.format(killRecap.getBaseExp() * assistData.getPercentage())))
                        .append("\n");
                if (assistData.getStreakExp() > 0) {
                    assistExp.append(CC.translate("&f连杀奖励: &b+" + this.pitCommands.numFormat.format(assistData.getStreakExp())))
                            .append("\n");
                }
                if (assistData.getLevelDisparityExp() > 0) {
                    assistExp.append(CC.translate("&f等级/装备差距: &b+" + this.pitCommands.numFormat.format(assistData.getLevelDisparityExp())))
                            .append("\n");
                }
                texts.add(Component.text(CC.translate("&0" + this.pitCommands.numFormat.format(assistData.getPercentage() * 100) + "% " + assistData.getDisplayName())));
                texts.add(newLine);
                texts.add(Component.text(CC.translate("&6+" + this.pitCommands.numFormat.format(assistData.getTotalCoin()) + "硬币"))
                        .hoverEvent(HoverEvent.showText(Component.text(assistCoin.toString())))
                        .append(
                                Component.text(CC.translate(" &b+" + this.pitCommands.numFormat.format(assistData.getTotalExp()) + "经验值"))
                                        .hoverEvent(HoverEvent.showText(Component.text(assistExp.toString())))
                        )
                );
                texts.add(newLine);
                texts.add(newLine);

                i++;
            }

            i = 1;


            texts.add(Component.text(CC.translate("&0&l伤害日志 (" + killRecap.getDamageLogs().size() + "):")));
            texts.add(newLine);

            for (cn.charlotte.pit.data.sub.KillRecap.DamageData damageData : killRecap.getDamageLogs()) {

                TextComponent info = Component.text(
                        CC.translate("&7" + ((killRecap.getCompleteTime() - damageData.getTimer().getStart()) / 1000)
                                + "秒前  &c"
                                + this.pitCommands.numFormat.format(damageData.getDamage())
                                + " "
                                + (damageData.isLava() ? "§c岩浆" : (damageData.isMelee() ? "§b近战" : "§d远程"))
                        )
                );

                if (damageData.getUsedItem() != null && damageData.getUsedItem().getType() != Material.AIR) {
                    info.hoverEvent(damageData.getUsedItem().asHoverEvent());
                }

                texts.add(info);
                texts.add(newLine);
                String damageHover = CC.translate((damageData.isAttack() ? "&7攻击目标 §b" + damageData.getDisplayName() : "&7来自 §b" + damageData.getDisplayName() + " §7的攻击")) +
                        "\n" +
                        CC.translate("§7剩余血量: &c" + this.pitCommands.numFormat.format(damageData.getAfterHealth()) +
                                "\n" +
                                CC.translate("&7附魔/天赋 附加伤害: &c" + this.pitCommands.numFormat.format(damageData.getBoostDamage())));

                texts.add(Component.text(CC.translate((damageData.isLava() ? "☼" :(damageData.isAttack() ? "&0⚔ " : "&0☬ ")) + damageData.getDisplayName()))
                        .hoverEvent(HoverEvent.showText(Component.text(damageHover)))
                );
                texts.add(newLine);
                texts.add(newLine);

                i++;
                if (i >= 5) {
                    i = 0;
                }
            }
            if (i > 0) {
//                pages.add(pageBuilder.build());
            }


            i = 0;
            TextComponent.Builder text = Component.text();
            for (Component component : texts){
                text.append(component);
                if (i == 13){
                    bookMeta.addPages(text.asComponent());
                    text = Component.text();
                    i = 0;
                    continue;
                }
                if (!newLine.equals(component)){
                    i++;
                }
            }
            bookMeta.addPages(text.asComponent());

            recapBook.setItemMeta(bookMeta);

            player.openBook(recapBook);
        } catch (Exception e) {
            CC.printError(player, e);
        }
        //todo: book
    }
    public static String getGoldBreakdown(ResourceManager manager) {
        StringBuilder builder = new StringBuilder();

        double baseGold = 0.0;

        // 基础金币来源显示
        builder.append("§f基础来源").append("\n");
        for (Map.Entry<String, Double> entry : manager.getGoldAdditions().entrySet()) {
            baseGold += entry.getValue();
            builder.append(CC.translate("  &f- " + entry.getKey() + ": &6" + (entry.getValue() > 0 ? "+" : "-") + PitCommands.numFormat.format(entry.getValue())))
                    .append("\n");
        }

        double bonus = 0.0;
        double penalty = 1.0;

        List<String> bonusLines = new ArrayList<>();
        List<String> penaltyLines = new ArrayList<>();

        // 处理倍率并分类保存显示行
        for (Map.Entry<String, Double> entry : manager.getGoldModifiers().entrySet()) {
            double val = entry.getValue();
            if (val > 1.0) {
                double added = val - 1.0;
                bonus += added;
                bonusLines.add(CC.translate("  &a - " + entry.getKey() + ": &a+" + PitCommands.numFormat.format(added * 100) + "%"));
            } else if (val < 1.0) {
                penalty *= val;
                penaltyLines.add(CC.translate("  &c - " + entry.getKey() + ": &c×" + PitCommands.numFormat.format(val)));
            }
            // 值为1的倍率不展示
        }

        // 先展示增益
        builder.append("§a增益倍率").append("\n");
        for (String line : bonusLines) {
            builder.append(line).append("\n");
        }
        // 再展示减益
        builder.append("§c减益倍率").append("\n");
        for (String line : penaltyLines) {
            builder.append(line).append("\n");
        }

        // 最终计算与展示
        double finalModifier = (1.0 + bonus) * penalty;
        double finalGold = baseGold * finalModifier;
        double cappedGold = Math.min(finalGold, manager.getMaxGold());

        builder.append(CC.translate("&f最终倍率: &e×" + PitCommands.numFormat.format(finalModifier))).append("\n");
        builder.append(CC.translate("&f实际金币: &6" + PitCommands.numFormat.format(cappedGold)));

        if (finalGold > manager.getMaxGold()) {
            builder.append(CC.translate(" &7(已达上限)"));
        }

        return builder.toString();
    }

    public static String getExpBreakdown(ResourceManager manager) {
        StringBuilder builder = new StringBuilder();

        double baseExp = 0.0;

        // 基础经验来源显示
        builder.append("§f基础来源").append("\n");
        for (Map.Entry<String, Double> entry : manager.getExpAdditions().entrySet()) {
            baseExp += entry.getValue();
            builder.append(CC.translate("&f - " + entry.getKey() + ": &b+" + PitCommands.numFormat.format(entry.getValue())))
                    .append("\n");
        }

        double bonus = 0.0;
        double penalty = 1.0;

        List<String> bonusLines = new ArrayList<>();
        List<String> penaltyLines = new ArrayList<>();

        // 处理倍率并分类保存显示行
        for (Map.Entry<String, Double> entry : manager.getExpModifiers().entrySet()) {
            double val = entry.getValue();
            if (val > 1.0) {
                double added = val - 1.0;
                bonus += added;
                bonusLines.add(CC.translate("&a - " + entry.getKey() + ": &a+" + PitCommands.numFormat.format(added * 100) + "%"));
            } else if (val < 1.0) {
                penalty *= val;
                penaltyLines.add(CC.translate("&c - " + entry.getKey() + ": &c×" + PitCommands.numFormat.format(val)));
            }
            // 值为1的倍率不展示
        }

        // 展示增益倍率
        builder.append("§a增益倍率").append("\n");
        for (String line : bonusLines) builder.append(line).append("\n");
        // 展示减益倍率
        builder.append("§c减益倍率").append("\n");
        for (String line : penaltyLines) builder.append(line).append("\n");

        // 最终计算与展示
        double finalModifier = (1.0 + bonus) * penalty;
        double finalExp = baseExp * finalModifier;
        double cappedExp = Math.min(Math.ceil(finalExp), manager.getMaxExp());

        builder.append(CC.translate("&f最终倍率: &e×" + PitCommands.numFormat.format(finalModifier))).append("\n");
        builder.append(CC.translate("&f实际经验: &b" + PitCommands.numFormat.format(cappedExp)));

        if (finalExp > manager.getMaxExp()) {
            builder.append(CC.translate(" &7(已达上限)"));
        }

        return builder.toString();
    }


}
